home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / program / 317 / asmsrc / input-fi.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-10-20  |  8.1 KB  |  321 lines

  1. /* input_file.c - -  */
  2.  
  3. /* Copyright (C) 1987 Free Software Foundation, Inc.
  4.  
  5. This file is part of Gas, the GNU Assembler.
  6.  
  7. The GNU assembler is distributed in the hope that it will be
  8. useful, but WITHOUT ANY WARRANTY.  No author or distributor
  9. accepts responsibility to anyone for the consequences of using it
  10. or for whether it serves any particular purpose or works at all,
  11. unless he says so in writing.  Refer to the GNU Assembler General
  12. Public License for full details.
  13.  
  14. Everyone is granted permission to copy, modify and redistribute
  15. the GNU Assembler, but only under the conditions described in the
  16. GNU Assembler General Public License.  A copy of this license is
  17. supposed to have been given to you along with the GNU Assembler
  18. so you can know your rights and responsibilities.  It should be
  19. in a file named COPYING.  Among other things, the copyright
  20. notice and this notice must be preserved on all copies.  */
  21.  
  22. /*
  23.  * Confines all details of reading source bytes to this module.
  24.  * All O/S specific crocks should live here.
  25.  * What we lose in "efficiency" we gain in modularity.
  26.  * Note we don't need to #include the "as.h" file. No common coupling!
  27.  */
  28.  
  29. #define NDEBUG        /* JF remove asserts */
  30.  
  31. #include <stdio.h>
  32. #include <assert.h>
  33. /* #include <sys/types.h>
  34. #include <sys/stat.h>
  35. #include <sys/file.h>
  36. #include <sys/wait.h> */
  37.  
  38. /* #include "style.h" */
  39. #include "input-file.h"
  40.  
  41. /* This variable is non-zero if the file currently being read should be
  42.    preprocessed by app.  It is zero if the file can be read straight in.
  43.  */
  44. int preprocess = 0;
  45.  
  46. void    as_perror();
  47.  
  48. /*
  49.  * This code opens a file, then delivers BUFFER_SIZE character
  50.  * chunks of the file on demand.
  51.  * BUFFER_SIZE is supposed to be a number chosen for speed.
  52.  * The caller only asks once what BUFFER_SIZE is, and asks before
  53.  * the nature of the input files (if any) is known.
  54.  */
  55.  
  56. #define BUFFER_SIZE (32 * 1024)
  57.  
  58. #ifdef atarist
  59. /* a little ditty here to do fread, filtering out '\r'. */
  60.  
  61. int filtering_fread(where, how_big, how_many, f)
  62. char * where;
  63. int how_big;
  64. int how_many;
  65. FILE * f;
  66. {
  67.   int i, j, c;
  68.  
  69.   for (i = 0 ; i < how_many ; )
  70.     {
  71.     for (j = 0 ; j < how_big ; )
  72.         {
  73.         c = fgetc(f);
  74.         if (c == EOF)
  75.             goto done;
  76.         if (c != '\r')
  77.             {
  78.             *where++ = c;
  79.             j++;
  80.             }
  81.         }
  82.     i++;
  83.     }
  84. done:
  85.   return(i);
  86. }
  87.  
  88. #else
  89.  
  90. static char in_buf[BUFFER_SIZE];
  91.  
  92. #endif
  93.  
  94. /*
  95.  * We use static data: the data area is not sharable.
  96.  */
  97.  
  98. /* static int    file_handle;    /* <0 === not open */
  99. FILE *f_in;    /* JF do things the RIGHT way */
  100. /* static JF remove static so app.c can use file_name */
  101. char *    file_name;
  102.  
  103. /* These hooks accomodate most operating systems. */
  104.  
  105. void
  106. input_file_begin ()
  107. {
  108.   /* file_handle = -1; */
  109.   f_in = (FILE *)0;
  110. }
  111.  
  112. void
  113. input_file_end ()
  114. {
  115. }
  116.  
  117. int                /* Return BUFFER_SIZE. */
  118. input_file_buffer_size ()
  119. {
  120.   return (BUFFER_SIZE);
  121. }
  122.  
  123. int
  124. input_file_is_open ()
  125. {
  126.   /* return (file_handle >= 0); */
  127.   return f_in!=(FILE *)0;
  128. }
  129.  
  130. #ifdef DONTDEF        /* JF save old version in case we need it */
  131. void
  132. input_file_open (filename, preprocess, debugging)
  133.      char *    filename;    /* "" means use stdin. Must not be 0. */
  134.      int    preprocess;    /* TRUE if needs app. */
  135.      int    debugging;    /* TRUE if we are debugging assembler. */
  136. {
  137.   assert( filename != 0 );    /* Filename may not be NULL. */
  138.   if (filename [0])
  139.     {                /* We have a file name. Suck it and see. */
  140.       file_handle = open (filename, O_RDONLY, 0);
  141.       file_name = filename;
  142.     }
  143.   else
  144.     {                /* use stdin for the input file. */
  145.       file_handle = fileno (stdin);
  146.       file_name = "{standard input}"; /* For error messages. */
  147.     }
  148.   if (file_handle < 0)
  149.     {
  150.       as_perror ("Can't open source file for input", file_name);
  151.     }
  152.   if ( preprocess )
  153.     {
  154. /*
  155.  * This code was written in haste for a frobbed BSD 4.2.
  156.  * I have a flight to catch: will someone please do proper
  157.  * error checks? - Dean.
  158.  */
  159.       int    pid;
  160.       char temporary_file_name [12];
  161.       int    fd;
  162.       union wait    status;
  163.       char    *mktemp();
  164.  
  165.       (void)strcpy (temporary_file_name, "#appXXXXXX");
  166.       (void)mktemp (temporary_file_name);
  167.       pid = vfork ();
  168.       if (pid == -1)
  169.     {
  170.       as_perror ("Can't fork to run app", file_name);
  171.       _exit (144);
  172.     }
  173.       if (pid == 0)
  174.     {
  175.       (void)dup2 (file_handle, fileno(stdin));
  176.       fd = open (temporary_file_name, O_WRONLY + O_TRUNC + O_CREAT, 0666);
  177.       if (fd == -1)
  178.         {
  179.           (void)write(2,"Can't open temporary\n",21);
  180.           _exit (99);
  181.         }
  182.       (void)dup2 (fd, fileno(stdout));
  183. /* JF for testing #define PREPROCESSOR "/lib/app" */
  184. #define PREPROCESSOR "./app"
  185.       execl (PREPROCESSOR, PREPROCESSOR, 0);
  186.       execl ("app","app",0);
  187.       (void)write(2,"Exec of app failed.  Get help.\n",31);
  188.       (void)unlink(temporary_file_name);
  189.       _exit (11);
  190.     }
  191.       (void)wait (& status);
  192.       if (status.w_status & 0xFF00)        /* JF was 0xF000, was wrong */
  193.     {
  194.       file_handle = -1;
  195.       as_warn( "Can't preprocess file \"%s\", status = %xx", file_name, status.w_status );
  196.     }
  197.       else
  198.     {
  199.       file_handle = open (temporary_file_name, O_RDONLY, 0);
  200.       if ( ! debugging )
  201.         {
  202.           if (unlink(temporary_file_name))
  203.         {
  204.           as_perror ("Can't delete temporary file, continuing", temporary_file_name);
  205.         }
  206.         }
  207.     }
  208.       if (file_handle == -1)
  209.     {
  210.       as_perror ("Can't retrieve temporary file", temporary_file_name);
  211.     }
  212.     }
  213. }
  214. #else
  215.  
  216. void
  217. input_file_open (filename,pre)
  218.      char *    filename;    /* "" means use stdin. Must not be 0. */
  219. {
  220.     int    c;
  221.     char    buf[80];
  222.  
  223.     preprocess = pre;
  224.  
  225.     assert( filename != 0 );    /* Filename may not be NULL. */
  226.     if (filename [0]) {    /* We have a file name. Suck it and see. */
  227.         f_in=fopen(filename,"r");
  228.         file_name=filename;
  229.     } else {            /* use stdin for the input file. */
  230.         f_in = stdin;
  231.         file_name = "{standard input}"; /* For error messages. */
  232.     }
  233.     if (f_in==(FILE *)0) {
  234.         as_perror ("Can't open source file for input", file_name);
  235.         return;
  236.     }
  237. #ifndef atarist
  238.     setbuffer(f_in,in_buf,BUFFER_SIZE);
  239. #endif
  240.     c=getc(f_in);
  241.     if(c=='#') {    /* Begins with comment, may not want to preprocess */
  242.         c=getc(f_in);
  243.         if(c=='N') {
  244.             fgets(buf,80,f_in);
  245.             if(!strcmp(buf,"O_APP\n"))
  246.                 preprocess=0;
  247.             if(!index(buf,'\n'))
  248.                 ungetc('#',f_in);    /* It was longer */
  249.             else
  250.                 ungetc('\n',f_in);
  251.         } else if(c=='\n')
  252.             ungetc('\n',f_in);
  253.         else
  254.             ungetc('#',f_in);
  255.     } else
  256.         ungetc(c,f_in);
  257.  
  258. #ifdef DONTDEF
  259.     if ( preprocess ) {
  260.         char temporary_file_name [17];
  261.         char    *mktemp();
  262.         FILE    *f_out;
  263.  
  264.         (void)strcpy (temporary_file_name, "/tmp/#appXXXXXX");
  265.         (void)mktemp (temporary_file_name);
  266.         f_out=fopen(temporary_file_name,"w+");
  267.         if(f_out==(FILE *)0) {
  268.             as_perror("Can't open temp file");
  269.         }
  270.             /* JF this will have to be moved on any system that
  271.                does not support removal of open files.  */
  272.         (void)unlink(temporary_file_name);/* JF do it NOW */
  273.         do_scrub(f_in,f_out);
  274.         (void)fclose(f_in);    /* All done with it */
  275.         (void)rewind(f_out);
  276.         f_in=f_out;
  277.     }
  278. #endif
  279. }
  280. #endif
  281.  
  282. char *
  283. input_file_give_next_buffer (where)
  284.      char *        where;    /* Where to place 1st character of new buffer. */
  285. {
  286.   char *    return_value;    /* -> Last char of what we read, + 1. */
  287.   register int    size;
  288.  
  289.   if (f_in == (FILE *)0)
  290.       return 0;
  291.       /*
  292.        * fflush (stdin); could be done here if you want to synchronise
  293.        * stdin and stdout, for the case where our input file is stdin.
  294.        * Since the assembler shouldn't do any output to stdout, we
  295.        * don't bother to synch output and input.
  296.        */
  297.   /* size = read (file_handle, where, BUFFER_SIZE); */
  298. #ifdef atarist
  299.   size= filtering_fread(where,sizeof(char),BUFFER_SIZE,f_in);
  300. #else
  301.   size= fread(where,sizeof(char),BUFFER_SIZE,f_in);
  302. #endif
  303.   if (size < 0)
  304.     {
  305.       as_perror ("Can't read source file: end-of-file faked.", file_name);
  306.       size = 0;
  307.     }
  308.   if (size)
  309.     return_value = where + size;
  310.   else
  311.     {
  312.       if (fclose (f_in))
  313.     as_perror ("Can't close source file -- continuing", file_name);
  314.       f_in = (FILE *)0;
  315.       return_value = 0;
  316.     }
  317.   return (return_value);
  318. }
  319.  
  320. /* end: input_file.c */
  321.